/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package de.realriu.snipzel.control.datastorage;

import com.uwyn.jhighlight.renderer.XhtmlRenderer;
import com.uwyn.jhighlight.renderer.XhtmlRendererFactory;
import de.realriu.riulib.helpers.ScaleImage;
import de.realriu.snipzel.Settings;
import de.realriu.snipzel.control.Controller;
import de.realriu.snipzel.model.CodeSnippet;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.net.URL;
import java.util.Date;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

/**
 *
 * @author riu
 */
public class FileStorage implements Storageable {

    private String workDir;
    private String praefix = "snip_";
    private String file_suffix = ".pet";
    private String url_suffix = ".html";
    
    private Controller control;
    

    public FileStorage(Controller c) {
        this.control = c;
        
    }


    public boolean saveSnippet(CodeSnippet cs) throws IOException {
        File f = new File(workDir+System.getProperty("file.separator")+praefix+cs.getId()+file_suffix);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));

        oos.writeLong(cs.getId());
        oos.writeUTF(cs.getTitle());
        oos.writeUTF(cs.getCode());
        oos.writeUTF(cs.getLanguage());
        oos.writeUTF(cs.getTags());
        
        
        oos.close();
        long v = Math.max(getMyVersion(), getCentralVersion()) + 1;
        PrintStream ps = new PrintStream(new File(workDir+System.getProperty("file.separator")+"version"));
        ps.println(v);
        ps.close();
        Settings.setSetting("version", ""+v);
        return true;
    }

    public boolean updateSnippet(CodeSnippet cs) throws IOException {
        return saveSnippet(cs);
    }

    public CodeSnippet loadSnippet(long id, boolean lazy) throws IOException {
        File f = new File(workDir+System.getProperty("file.separator")+praefix+id+file_suffix);
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));

        id = ois.readLong();
        String title = "";
        String code = "";
        String lang = "";
        String tags = "";

        try{
        title = ois.readUTF();
        code = ois.readUTF();
        lang = ois.readUTF();
        tags = ois.readUTF();
        }catch(EOFException e){}

        if(!XhtmlRendererFactory.getSupportedTypes().contains(lang)){
            lang = CodeSnippet.UNKNOWN_LANGUAGE_STRING;
        }
        ois.close();

        if(lazy){
            return new CodeSnippet(id, title, lang, tags);
        }else{
            
            return new CodeSnippet(id, title, lang, code, tags);
        }

    }

    public CodeSnippet[] loadAllSnippets(boolean lazy) throws IOException {
        File work = new File(workDir);
        File[] files = work.listFiles(new FileFilter() {

            public boolean accept(File file) {
                return file.getName().startsWith(praefix) && file.getName().endsWith(file_suffix);
            }
        });

        CodeSnippet[] snippets = new CodeSnippet[files.length];

        for(int i=0; i<files.length; i++){
            long id = Long.parseLong(files[i].getName().replace(praefix, "").replace(file_suffix, ""));
            snippets[i] = loadSnippet(id, true);
        }

        return snippets;
    }

    public boolean deleteSnippet(CodeSnippet cs) throws IOException {
        if(cs != null){
            
            //new File(Settings.LIBRARY_DIR+System.getProperty("file.separator")+praefix+cs.getId()+url_suffix).delete();
            new File(workDir+System.getProperty("file.separator")+praefix+cs.getId()+file_suffix).delete();

            long v = Math.max(getMyVersion(), getCentralVersion()) + 1;
            PrintStream ps = new PrintStream(new File(workDir+System.getProperty("file.separator")+"version"));
            ps.println(v);
            ps.close();
            Settings.setSetting("version", ""+v);
            return true;
        }
        else{
            return false;
        }
    }

    public boolean initWorkDirectory() throws IOException {
        workDir = Settings.getSetting("work-dir");
        if(workDir == null){
            JOptionPane.showMessageDialog(control.getMainFrame(), "Es wurde noch kein Arbeitsverzeichnis ausgewählt, bitte tun Sie das jetzt.");
            JFileChooser fc = new JFileChooser(System.getProperty("user.home"));
            fc.setDialogTitle("Arbeitsverzeichnis auswählen");
            fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            fc.setMultiSelectionEnabled(false);
            if(fc.showOpenDialog(control.getMainFrame()) != JFileChooser.APPROVE_OPTION){
                System.exit(0);
            }else{
                Settings.setSetting("work-dir", fc.getSelectedFile().getAbsolutePath());
                workDir = Settings.getSetting("work-dir");
            }

            if(Settings.getSetting("version") == null){
                Settings.setSetting("version", ""+getCentralVersion());
            }
        }

        return true;
    }

    public String getURL(CodeSnippet cs) throws IOException {
        //File f = new File(workDir+System.getProperty("file.separator")+praefix+cs.getId()+url_suffix);
        File f = new File(Settings.LIBRARY_DIR+System.getProperty("file.separator")+praefix+url_suffix);
        PrintStream ps = new PrintStream(f);
        StringTokenizer st = new StringTokenizer(cs.getHTMLCode(), "\n");
        while(st.hasMoreTokens()){
            ps.println(st.nextToken());
        }
        ps.close();
        //return new URL("file", "", workDir+System.getProperty("file.separator")+praefix+cs.getId()+url_suffix).toString();
        return new URL("file", "", f.getAbsolutePath()).toString();
        //return "file://"+workDir+System.getProperty("file.separator")+praefix+cs.getId()+url_suffix;
    }

    public synchronized long getNewSnippetID() throws IOException {
        long id = 0;

        File fn = new File(workDir+System.getProperty("file.separator")+praefix+id+file_suffix);
        while(fn.exists()){
            id++;
            fn = new File(workDir+System.getProperty("file.separator")+praefix+id+file_suffix);
        }
        
        return id;
    }


    public long getCentralVersion() throws IOException {
        long v = Long.MIN_VALUE;
        try{
            BufferedReader br = new BufferedReader(new FileReader(new File(workDir+System.getProperty("file.separator")+"version")));
            String l = br.readLine();
            v = Long.parseLong(l);
        }catch(Exception e){
            PrintStream ps = new PrintStream(new File(workDir+System.getProperty("file.separator")+"version"));
            ps.println(v);
            ps.close();           
        }

        return v;
    }

    public long getMyVersion() throws IOException {
        long v = Long.MIN_VALUE;
        try{
            v = Long.parseLong(Settings.getSetting("version"));
        }catch(Exception e){
            Settings.setSetting("version", v+"");
        }
        return v;
    }



}
